home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 201-225 / disk_224 / climax / movesys.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  6KB  |  232 lines

  1. /* This program will reassign all the standard assigned names to be the proper
  2.    usual directories on a new disk.  The names are:
  3.  
  4.     C:  DEVS:  FONTS:  L:  LIBS:  S:  and SYS:
  5.  
  6.    This program will assign SYS: to the given volume and each of the other
  7.    names to the directory of SYS: with that same name (C: = SYS:c etc).
  8.    
  9.    It's called MoveSys.  Hard disk users can put it in their Startup-Sequence
  10.    to ease the transition from the floppy boot disk (or RAD:) to the hard
  11.    disk.  Non-hard-disk users can use it to switch from one bootable
  12.    application disk to another without getting "please insert volume
  13.    Workbench 1.3" or the like all the time.  For Aztec C.  If you want
  14.    flexibility, customize the source code.  Usage:
  15.  
  16.     MoveSys name:        ; where name is a volume name or drive name
  17.  
  18.    You can even MoveSys to a directory, if the appropriate subdirectories
  19.    are present there.  Like, MoveSys dh0:Workbench or something.
  20.  
  21.    By Paul Kienitz, 12/10/88.  Public domain.  For Aztec C only; do not
  22.    compile with the +m flag.  The result is "pure" and can be made resident.
  23.    
  24.    1/17/89:  Ooops!  Had to add DosAllocate, because unassigning a node I
  25.    created without that could cause bad craziness.  I should put DosAllocate
  26.    into AssignDev, though it's probably not needed if I fix the bug in
  27.    detecting whether a node it's deleting is one it made, which I think
  28.    somebody already did.
  29.  
  30.    4/14/89:  Stripped down internally (no stdio, for instance) to reduce size
  31.    and make "pure".  Added IoErr code return.
  32.  
  33.    ADD LATER:   arguments after volume name to be exceptions or additions to
  34.             the built-in list of assignments.
  35.         ability to run from workbench, using workbench message and
  36.          tooltypes.
  37.         make it not reassign SYS: when locks fail on dirs?
  38.  */
  39.  
  40.  
  41.  
  42. #include <exec/types.h>
  43. #include <exec/nodes.h>
  44. #include <exec/lists.h>
  45. #include <exec/memory.h>
  46. #include <exec/ports.h>
  47. #include <exec/libraries.h>
  48. #include <exec/devices.h>
  49. #include <exec/io.h>
  50. #include <libraries/dosextens.h>
  51. #include <libraries/filehandler.h>
  52. #ifdef AZTEC_C
  53. #include <functions.h>
  54. #endif
  55. #include <Paul.h>  /* defines null, adr, str, bool, bip, gbip, AllocXX ... */
  56.  
  57.  
  58. typedef struct DeviceNode den;
  59. typedef BPTR lock;
  60.  
  61. #define HowMany 6
  62. char *dames[HowMany] = {"C", "DEVS", "FONTS", "L", "LIBS", "S"};
  63. char *dears[HowMany] = {"SYS:c", "SYS:devs", "SYS:fonts", "SYS:l",
  64.             "SYS:libs", "SYS:s"};
  65. /* SYS: gets assigned to the volume named in the command line argument (or
  66.    workbench message argument someday), and then each name in dames gets
  67.    assigned to the corresponding directory name in dears.  You can change
  68.    dears to e.g. assign C: to RAM:C or whatever, or add more names to each,
  69.    incrementing HowMany to match. */
  70.  
  71.  
  72. /* the only global variables are unchanging, e.g. library bases */
  73.  
  74. extern struct DosLibrary *DOSBase;
  75. struct DosInfo *infoo;            /* contains the root of the dev list */
  76.  
  77.  
  78.  
  79. #undef put  /* defined as fputs(stdout, S) in Paul.h */
  80.  
  81. void put(s) str s;
  82. {    long o = Output();
  83.     if (o) Write(o, s, (long) strlen(s));
  84. }
  85.  
  86.  
  87.  
  88. /* Allocate a block of memory the way the Dos does, with size (rounded up to
  89.    the nearest multiple of four) in the longword below the address returned */
  90.  
  91. adr DosAllocate(size) int size;
  92. {
  93.     long longlen = (size + 7) & ~3L;
  94.     long *dosalloc = AllocPZ(longlen);
  95.     if (!dosalloc) return (null);
  96.     *dosalloc = longlen;
  97.     return (dosalloc + 1);
  98. }
  99.  
  100.  
  101.  
  102. void DosFree(a) long *a;
  103. {    FreeMem(a - 1, a[-1]);
  104. }
  105.  
  106.  
  107.  
  108. den *MakeNewAssignNode(name) str name;   /* do this within a Forbid */
  109. {    
  110.     den *foo = DosAllocate(sizeof(den));
  111.     int len = strlen(name);
  112.     str nom;
  113.     if (!foo) return (null);
  114.     if (!(nom = DosAllocate(len + 2))) {  /* room for length byte AND  */
  115.         DosFree(foo);                 /*  nul, like existing nodes */
  116.         return (null);
  117.     }
  118.     foo->dn_Name = (long) nom >> 2;
  119.     foo->dn_Type = 1L;
  120.     nom[0] = len;
  121.     strcpy(nom + 1, name);    /* leave the nul on the end */
  122.     foo->dn_Next = infoo->di_DevInfo;    /* put new node at top of list */
  123.     infoo->di_DevInfo = (long) foo >> 2;
  124.     return (foo);
  125. }
  126.  
  127.  
  128.  
  129. bool Match(s, b) str s; BSTR b;
  130. {
  131.     str bee = bip(char, b);
  132.     short len = strlen(s);
  133.     short i;
  134.     if (bee[0] != len) return (false);
  135.     for (i = 0; i < len; i++)
  136.         if (toupper(s[i]) != toupper(bee[i + 1]))
  137.             return (false);
  138.     return (true);
  139. }
  140.  
  141.  
  142.  
  143. den *FindDNode(name) str name;
  144. {
  145.     den *goob;
  146.     for (goob = gbip(infoo->di_DevInfo); goob; goob = gbip(goob->dn_Next))
  147.         if (goob->dn_Type == 1 && Match(name, goob->dn_Name))
  148.             return (goob);
  149.     return (null);
  150. }
  151.  
  152.  
  153.  
  154. bool ReAssign(name, lok) str name; lock lok;
  155. {
  156.     den *where;
  157.     lock old;
  158.     Forbid();
  159.     where = FindDNode(name);
  160.     if (!where) where = MakeNewAssignNode(name);
  161.     if (!where) {
  162.         Permit();
  163.         put("Couldn't find or create device node for \"");
  164.         put(name);
  165.         put("\".\nOut of memory, I guess.\n");
  166.         return (false);
  167.     }
  168.     old = where->dn_Lock;
  169.     where->dn_Lock = lok;
  170.     where->dn_Task = bip(struct FileLock, lok)->fl_Task;
  171.     Permit();
  172.     UnLock(old);
  173.     return (true);
  174. }
  175.  
  176.  
  177.  
  178.  
  179. long _main(alen, aptr) long alen; str aptr;
  180. {
  181.     lock syl, L;
  182.     short f;
  183.     long hair = 0, turn = 0;
  184.     struct Process *me = (adr) FindTask(null);
  185.  
  186.     infoo = bip(struct DosInfo, 
  187.             ((struct RootNode *) DOSBase->dl_Root) ->rn_Info);
  188.     while (alen && aptr[alen - 1] <= ' ') aptr[--alen] = 0;
  189.     if (*aptr == '"') {
  190.         if (aptr[alen - 1] == '"') aptr[--alen] = 0;
  191.         aptr++;
  192.     }
  193.     if (alen && !(alen == 1 && *aptr == '?'))
  194.         syl = (BPTR) RLock(aptr);
  195.     else {
  196.         put(
  197. "You must name a drive, volume, or directory to move SYS: to.\n");
  198.         me->pr_Result2 = ERROR_LINE_TOO_LONG;
  199.         return (10L);
  200.     }
  201.     if (!syl) {
  202.         hair = me->pr_Result2;            /* set by Lock */
  203.         put("MoveSys couldn't find drive/volume \"");
  204.         put(aptr);
  205.         put("\".\n");
  206.         me->pr_Result2 = hair;
  207.         return (10L);
  208.     }
  209.     if (!ReAssign("SYS", syl)) {
  210.         turn = 10;
  211.         hair = ERROR_NO_FREE_STORE;
  212.     } else for (f = 0; f < HowMany; f++) {
  213.         L = (BPTR) RLock(dears[f]);
  214.         if (!L) {
  215.             turn = 5;
  216.             hair = me->pr_Result2;    /* set by Lock */
  217.             put("MoveSys couldn't find directory \"");
  218.             put(dears[f]);
  219.             put("\" (SYS: = \"");
  220.             put(aptr);
  221.             put("\").\n");
  222.         } else
  223.             if (!ReAssign(dames[f], L)) {
  224.                 turn = 10;
  225.                 hair = ERROR_NO_FREE_STORE;
  226.                 break;
  227.             }
  228.     }
  229.     me->pr_Result2 = hair;
  230.     return (turn);
  231. }
  232.